package io.renren.modules.sys.controller;

import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.RandomStringUtils;
import org.apache.shiro.crypto.hash.Sha256Hash;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.toolkit.StringUtils;

import io.renren.common.utils.R;
import io.renren.modules.frt.entity.DistrictEntity;
import io.renren.modules.frt.service.DistrictService;
import io.renren.modules.sys.constant.DictConst;
import io.renren.modules.sys.entity.SysUserEntity;
import io.renren.modules.sys.form.SysLoginForm;
import io.renren.modules.sys.service.SysCaptchaService;
import io.renren.modules.sys.service.SysUserRoleService;
import io.renren.modules.sys.service.SysUserService;
import io.renren.modules.sys.service.SysUserTokenService;

/**
 * 登录相关
 * 
 * @author chenshun
 * @email sunlightcs@gmail.com
 * @date 2016年11月10日 下午1:15:31
 */
@RestController
public class SysLoginController extends AbstractController {
	@Autowired
	private SysUserService sysUserService;
	@Autowired
	private SysUserTokenService sysUserTokenService;
	@Autowired
	private SysCaptchaService sysCaptchaService;
	@Autowired
    private DistrictService districtService;
	@Autowired
	private SysUserRoleService sysUserRoleService;

	/**
	 * 验证码
	 */
	@GetMapping("captcha.jpg")
	public void captcha(HttpServletResponse response, String uuid)throws ServletException, IOException {
		response.setHeader("Cache-Control", "no-store, no-cache");
		response.setContentType("image/jpeg");

		//获取图片验证码
		BufferedImage image = sysCaptchaService.getCaptcha(uuid);

		ServletOutputStream out = response.getOutputStream();
		ImageIO.write(image, "jpg", out);
		IOUtils.closeQuietly(out);
	}

	/**
	 * 登录
	 */
	@PostMapping("/sys/login")
	public Map<String, Object> login(@RequestBody SysLoginForm form)throws IOException {
		boolean captcha = sysCaptchaService.validate(form.getUuid(), form.getCaptcha());
		if(!captcha){
			return R.error("验证码不正确");
		}

		//用户信息，可以使用用户名或者邮箱登录
		SysUserEntity user = sysUserService.queryByUserName(form.getUsername());

		//账号不存在、密码错误
		if(user == null || !user.getPassword().equals(new Sha256Hash(form.getPassword(), user.getSalt()).toHex())) {
			return R.error("账号或密码不正确");
		}

		//账号锁定
		if(user.getStatus() == 0){
			return R.error("账号已被锁定,请联系管理员");
		}
		
		if(user.getCheckStatus() != 1){
			return R.error("未审核或审核不通的账号不能登录，请联系管理员");
		}

		//生成token，并保存到数据库
		R r = sysUserTokenService.createToken(user.getUserId());
		r.put("userId", user.getUserId()).put("level", user.getLevel())
		.put("province", user.getProvince()).put("city", user.getCity()).put("country", user.getCountry());
		return r;
	}
	
	/**
	 * 注册
	 */
	@PostMapping("/sys/register")
	public Map<String, Object> register(@RequestBody SysLoginForm form)throws IOException {
		
		if(StringUtils.isEmpty(form.getEmail())) {
			return R.error("邮箱不能为空");
		}
		
		SysUserEntity dbUser = sysUserService.selectOne(new EntityWrapper<SysUserEntity>().eq("email", form.getEmail()));
		if(dbUser != null) {
			return R.error("该邮箱已经注册");
		}
		
		SysUserEntity dbUser2 = sysUserService.selectOne(new EntityWrapper<SysUserEntity>().eq("username", form.getUsername()));
		if(dbUser2 != null) {
			return R.error("该用户账号已经注册");
		}
		
		SysUserEntity user = new SysUserEntity();
		user.setCreateTime(new Date());
		user.setEmail(form.getEmail());
		user.setEmployer(form.getEmployer());
		user.setUsername(form.getUsername());
		
		user.setLevel(form.getLevel());
		List<Long> roleIdList = new ArrayList<>();
		
		if(DictConst.USER_LEVEL.PROVINCE.getKey() == form.getLevel()) {
			if(StringUtils.isEmpty(form.getProvince())) {
				return R.error("省份不能为空");
			}
			SysUserEntity db = sysUserService
					.selectOne(new EntityWrapper<SysUserEntity>().eq("province", form.getProvince()).eq("level", form.getLevel()));
			if (db != null) {
				return R.error("该省级用户已存在");
			}
			user.setProvince(form.getProvince());
			
			SysUserEntity parent = sysUserService.selectOne(new EntityWrapper<SysUserEntity>().eq("level", DictConst.USER_LEVEL.ADMIN.getKey()));
			if(parent == null) {
				return R.error("管理员有且仅有一个");
			}
			user.setParentId(parent.getUserId());//需要自动关了父级
			roleIdList.add(DictConst.DEFAULT_ROLE_ID.PROVINCE.getKey());
		}else if(DictConst.USER_LEVEL.CITY.getKey() == form.getLevel()) {
			if(StringUtils.isEmpty(form.getProvince())) {
				return R.error("省份不能为空");
			}
			if(StringUtils.isEmpty(form.getCity())) {
				return R.error("市不能为空");
			}
			SysUserEntity db = sysUserService
					.selectOne(new EntityWrapper<SysUserEntity>().eq("city", form.getCity()).eq("level", form.getLevel()));
			if (db != null) {
				return R.error("该市级用户已存在");
			}
			user.setProvince(form.getProvince());
			user.setCity(form.getCity());
			
			SysUserEntity parent = sysUserService.selectOne(new EntityWrapper<SysUserEntity>()
					.eq("level", DictConst.USER_LEVEL.PROVINCE.getKey()).eq("province", form.getProvince()));
			user.setParentId(parent.getUserId());//需要自动关了父级
			roleIdList.add(DictConst.DEFAULT_ROLE_ID.CITY.getKey());
		}else if(DictConst.USER_LEVEL.COUNTRY.getKey() == form.getLevel()) {
			if(StringUtils.isEmpty(form.getProvince())) {
				return R.error("省份不能为空");
			}
			if(StringUtils.isEmpty(form.getCity())) {
				return R.error("市不能为空");
			}
			if(StringUtils.isEmpty(form.getCountry())) {
				return R.error("县不能为空");
			}
			SysUserEntity db = sysUserService
					.selectOne(new EntityWrapper<SysUserEntity>().eq("country", form.getCountry()).eq("level", form.getLevel()));
			if (db != null) {
				return R.error("该县级用户已存在");
			}
			user.setProvince(form.getProvince());
			user.setCity(form.getCity());
			user.setCountry(form.getCountry());
			
			SysUserEntity parent = sysUserService.selectOne(new EntityWrapper<SysUserEntity>()
					.eq("level", DictConst.USER_LEVEL.CITY.getKey()).eq("city", form.getCity()));
			user.setParentId(parent.getUserId());//需要自动关了父级
			roleIdList.add(DictConst.DEFAULT_ROLE_ID.COUNTRY.getKey());
		}else if(DictConst.USER_LEVEL.NONE.getKey() == form.getLevel()) {
			if(StringUtils.isEmpty(form.getProvince())) {
				return R.error("省份不能为空");
			}
			if(StringUtils.isEmpty(form.getCity())) {
				return R.error("市不能为空");
			}
			if(StringUtils.isEmpty(form.getCountry())) {
				return R.error("县不能为空");
			}
			user.setProvince(form.getProvince());
			user.setCity(form.getCity());
			user.setCountry(form.getCountry());
			
			SysUserEntity parent = sysUserService.selectOne(new EntityWrapper<SysUserEntity>()
					.eq("level", DictConst.USER_LEVEL.COUNTRY.getKey()).eq("country", form.getCountry()));
			user.setParentId(parent.getUserId());//需要自动关了父级
			roleIdList.add(DictConst.DEFAULT_ROLE_ID.NONE.getKey());
		}
		user.setMobile(form.getMobile());
		user.setPosition(form.getPosition());
		user.setRealname(form.getUsername());
		//sha256加密
		String salt = RandomStringUtils.randomAlphanumeric(20);
		user.setPassword(new Sha256Hash(form.getPassword(), salt).toHex());
		user.setSalt(salt);
		
		user.setStatus(1);//默认正常
		user.setCheckStatus(0);//默认未审核
		user.setTenantId(1l);//默认为1
		
		sysUserService.insert(user);
		
		//初始化默认角色
		if(user.getUserId() != null && roleIdList.size() == 1) {
			sysUserRoleService.saveOrUpdate(user.getUserId(), roleIdList);
		}
		
		return R.ok();
	}
	
	/**
	 * 行政区列表
	 */
	@GetMapping("/sys/register/select")
	public R select(@RequestParam Map<String, Object> params){
		Map<String, Object> map = new HashMap<>();
		map.put("level", params.get("level"));
		map.put("parent_code", params.get("parentCode"));
		List<DistrictEntity> list = districtService.selectByMap(map);
		
		return R.ok().put("list", list);
	}


	/**
	 * 退出
	 */
	@PostMapping("/sys/logout")
	public R logout() {
		sysUserTokenService.logout(getUserId());
		return R.ok();
	}
	
}
